// ignore_for_file: prefer_interpolation_to_compose_strings

import 'package:dio/dio.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:get/get_core/src/get_main.dart';
import 'package:get/get_instance/get_instance.dart';
import 'package:get/get_navigation/get_navigation.dart';
import 'package:FiduMart/core/utils/common_util.dart';
import 'package:FiduMart/core/utils/logger.dart';
import 'package:FiduMart/core/utils/pref_utils.dart';

/**
 * 网络请求封装,使用前需要先调用setToken方法设置token
 */
class RequestClient {
  static RequestClient? _instance;

  late Dio _dio;


  static String token = "";
  // static String token = "";


  final pref = Get.find<PrefUtils>();
  /**
   * 工厂构造方法
   */
  factory RequestClient() {
    if (_instance == null) {
      _instance = RequestClient._internal();
    }
    return _instance!;
  }

  /**
   * 私有构造方法
   */
  RequestClient._internal() {
    initDio();
    print("RequestClient init");
  }

  static const String BASE_URL_TEST = "http://120.27.219.251:13000";
  // static const String BASE_URL_TEST = "https://h5-club.umcrypto.io/business";

  static const String BASE_URL_RELEASE = "https://umcrypto.io";
  static const String BASE_URL =
      kReleaseMode ? BASE_URL_RELEASE : BASE_URL_TEST;

  Future<void> initDio() async {
    _dio = Dio();
    _dio.options.baseUrl = BASE_URL;
    _dio.options.connectTimeout = const Duration(seconds: 30);
    _dio.options.receiveTimeout = const Duration(seconds: 30);
    _dio.options.headers = {
      "client-type": "app",
      "Token": token,
      "version": "200",
      "app-type": "android"
    };
    _dio.interceptors.add(LogInterceptor(
        responseBody: true,
        requestBody: true,
        requestHeader: true,
        request: true));

    token = await pref.getToken();
    setToken(token);
  }

  Future<void> setToken(String token) async {
    //判断token是否相等
    if (RequestClient.token == token) {
      return;
    }
    RequestClient.token = token;
    await pref.setToken(token);
    // _dio.options.headers["Token"] = token;
    initDio();
  }

  Future<T> getNoParams<T>(String path, [bool? showDialog]) async {
    if (showDialog == true) {
      EasyLoading.show();
    }
    try {
      final response = await _dio.get(path);
      return parseResponse(response);
    } on DioException catch (e) {
      throw formatError(e);
    } catch (e) {
      throw e;
    } finally {
      if (showDialog == true) {
        EasyLoading.dismiss();
      }
    }
  }

  // get 请求-有参
  Future<T> get<T>(String path, Map<String, dynamic> params,
      [bool? showDialog]) async {
    Logger.log("dio request params:$params");
    if (showDialog == true) {
      EasyLoading.show(status: 'loading...');
    }
    try {
      final response = await _dio.get(path, queryParameters: params);
      return parseResponse(response);
    } on DioException catch (e) {
      CommonUtil.showErrorToast("网络失败: ${e.message}");
      throw formatError(e);
    } catch (e) {
      CommonUtil.showErrorToast("$e");
      throw e;
    } finally {
      if (showDialog == true) {
        EasyLoading.dismiss();
      }
    }
  }

  // post 请求
  Future<T> post<T>(String path, Map<String, dynamic> params,
      [bool? showDialog]) async {
    Logger.log("dio request params:$params;");
    if (showDialog == true) {
      EasyLoading.show(status: 'loading...');
    }
    try {
      final response = await _dio.post(path, data: params);
      return parseResponse(response);
    }on DioException catch (e) {
      CommonUtil.showErrorToast("网络失败: ${e.message}");
      throw formatError(e);
    } catch (e) {
      CommonUtil.showErrorToast("$e");
      throw e;
    }finally {
      if (showDialog == true) {
        EasyLoading.dismiss();
      }
    }
  }

  //post 文件
  Future<T> postFile<T>(String path, FormData params,
      [bool? showDialog]) async {
    Logger.log("dio request params:$params;");
    if (showDialog == true) {
      EasyLoading.show(status: 'loading...');
    }
    try {
      final response = await _dio.post(path, data: params);
      return parseResponse(response);
    }on DioException catch (e) {
      CommonUtil.showErrorToast("网络失败: ${e.message}");
      throw formatError(e);
    } catch (e) {
      CommonUtil.showErrorToast("$e");
      throw e;
    }finally {
      if (showDialog == true) {
        EasyLoading.dismiss();
      }
    }
  }

  // delete 请求
  Future<T> delete<T>(String path, Map<String, dynamic> params,
      [bool? showDialog]) async {
    Logger.log("dio request params:$params");
    if (showDialog == true) {
      EasyLoading.show(status: 'loading...');
    }
    try {
      final response = await _dio.delete(path, queryParameters: params);
      return parseResponse(response);
    } on DioException catch (e) {
      CommonUtil.showErrorToast("网络失败: ${e.message}");
      throw formatError(e);
    } catch (e) {
      CommonUtil.showErrorToast("$e");
      throw e;
    } finally {
      if (showDialog == true) {
        EasyLoading.dismiss();
      }
    }
  }

  // 解析响应数据
  dynamic parseResponse(Response response) {
    if (response.statusCode == 200) {
      var responseData = response.data;

      if (responseData["code"] == 1004) {
        if (!Get.isBottomSheetOpen!) {
          
        }
        return;
      }else if(responseData["code"] == 2004){
        return responseData;
      }else if(responseData["code"] == 8001){
        return responseData;
      }else if(responseData["code"] == 8002){
        return responseData;
      }else if(responseData["code"] == 5002){
        return responseData;
      }
      else if (responseData["code"] != 1 && responseData["code"] != 200) {
        throw Exception(responseData["message"]);
      }
      return responseData;
    } else {
      throw Exception(response.statusMessage);
    }
  }

  // 格式化错误信息
  dynamic formatError(DioException e) {
    switch (e.type) {
      case DioExceptionType.connectionTimeout:
        return {"error": "连接超时"};
      case DioExceptionType.sendTimeout:
        return {"error": "请求超时"};
      case DioExceptionType.receiveTimeout:
        return {"error": "响应超时"};
      case DioExceptionType.badResponse:
        return {"error": "接口错误", "msg": e.message};
      case DioExceptionType.cancel:
        return {"error": "请求取消"};
      default:
        return {"error": "未知错误", "msg": e.message};
    }
  }



}
